import {Sequences} from "../composite/composite.sequences";
import {EStatus} from "../EStatus";
import {NodeTypes} from "../NodeTypes";
import {Selector} from "../composite/composite.selector";

const getSourceChildren = [
    {
        type: NodeTypes.Leaf,
        action: notFullSource
    },
    {
        type: NodeTypes.Leaf,
        action: ({creep, sourceId}) => {
            let source: Source = Game.getObjectById<Source>(sourceId);
            if (creep.harvest(source) == ERR_NOT_IN_RANGE) creep.moveTo(source)
        }
    }
]
const transferSourceChildren = [
    {
        type: NodeTypes.Leaf,
        action: fullSource
    },
    {
        type: NodeTypes.Leaf,
        action: ({creep, targetId}) => {
            let target: Source = Game.getObjectById(targetId);
            if (creep.transfer(target, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) creep.moveTo(target)
        }
    }
]

function fullSource({creep}) {
    if ('store' in creep && creep.store[RESOURCE_ENERGY] >= creep.store.getCapacity()) {
        return EStatus.Success;
    } else
        return EStatus.Failure;
}

function notFullSource({creep}) {
    if ('store' in creep && creep.store[RESOURCE_ENERGY] < creep.store.getCapacity()) {
        return EStatus.Success;
    } else
        return EStatus.Failure;
}

function getRoot() {
    const sequence: Selector = new Selector();
    const getSource: Sequences = new Sequences();
    getSource.children = getSourceChildren;
    const transferSource: Sequences = new Sequences();
    transferSource.children = transferSourceChildren;
    sequence.children = [getSource, transferSource];
    return sequence;
}


export function harvesterTree(sourceId, targetId) {
    return function (creep) {
        let root: Selector;
        if (global.treeModel === undefined)
            global.treeModel = {};
        if (global.treeModel.harvesterTree) {
            root = global.treeModel.harvesterTree
        } else {
            root = getRoot();
            global.treeModel.harvesterTree = root;
        }
        return root.action({creep, sourceId, targetId});
    }
}

